import java.util.Scanner; // 导入Scanner类，用于接收用户输入

public class PhoneBookMain { // 主程序类，包含程序的入口点main方法

    public static void main(String[] args) { // 程序入口方法，Java程序从这里开始执行，main方法是程序入口，固定格式：public static void main(String[]
                                             // args)
        PhoneBookManagerImpl manager = new PhoneBookManagerImpl(); // 创建电话簿管理器对象
        Scanner scanner = new Scanner(System.in); // 创建输入扫描器，从控制台读取用户输入

        while (true) { // 无限循环，直到用户选择退出
            System.out.println("\n=== 电话簿管理系统 ==="); // 打印系统标题
            System.out.println("1. 添加联系人  2. 删除联系人  3. 修改联系人  4. 查找联系人  5. 显示所有联系人  6. 退出"); // 显示菜单选项
            System.out.print("请选择操作: "); // 提示用户输入
            int choice = scanner.nextInt(); // 读取用户选择的整数
            scanner.nextLine(); // 消耗回车符，nextLine()用于读取整行包含空格的输入

            try { // try块处理可能出现的异常，Java异常处理机制
                switch (choice) { // switch语句根据用户选择执行不同操作，相当于多个if-else
                    case 1:
                        addContact(manager, scanner); // 调用添加联系人方法
                        break; // break语句跳出switch，防止继续执行下面的case
                    case 2:
                        deleteContact(manager, scanner); // 调用删除联系人方法
                        break; // break语句跳出switch
                    case 3:
                        updateContact(manager, scanner); // 调用修改联系人方法
                        break; // break语句跳出switch
                    case 4:
                        searchContact(manager, scanner); // 调用查找联系人方法
                        break; // break语句跳出switch
                    case 5:
                        showAllContacts(manager); // 调用显示所有联系人方法
                        break; // break语句跳出switch
                    case 6:
                        System.out.println("感谢使用！"); // 打印退出信息
                        return; // return语句结束main方法，程序退出
                    default:
                        System.out.println("无效选择，请重新输入！"); // default处理无效输入，相当于else
                }
            } catch (Exception e) { // catch块捕获异常，Exception是所有异常的父类
                System.out.println("操作失败: " + e.getMessage()); // 显示异常信息，getMessage()获取异常详情
            }
        }
    }

    private static void addContact(PhoneBookManagerImpl manager, Scanner scanner) { // 添加联系人的私有静态方法，private限制访问权限，static表示类方法
        System.out.print("姓名: "); // 打印提示信息，print不换行
        String name = scanner.nextLine(); // 获取姓名输入，nextLine()读取整行字符串
        System.out.print("性别(男/女): "); // 打印性别提示
        String gender = scanner.nextLine(); // 获取性别输入
        System.out.print("年龄: "); // 打印年龄提示
        int age = scanner.nextInt(); // 获取年龄输入，nextInt()读取整数
        scanner.nextLine(); // 消耗回车符，防止影响下次输入
        System.out.print("地址: "); // 打印地址提示
        String address = scanner.nextLine(); // 获取地址输入
        System.out.print("电话: "); // 打印电话提示
        String phone = scanner.nextLine(); // 获取电话输入
        System.out.print("邮箱(可选): "); // 打印邮箱提示
        String email = scanner.nextLine(); // 获取邮箱输入

        Contact contact = new Contact(name, gender, age, address, phone, email.isEmpty() ? null : email); // 创建联系人对象，使用三元运算符：条件?值1:值2
        if (manager.addContact(contact)) // if语句判断添加是否成功，addContact返回boolean
            System.out.println("添加成功！"); // 成功时打印信息
        else
            System.out.println("添加失败！可能是重复联系人或信息无效。"); // 失败时打印信息
    }

    private static void deleteContact(PhoneBookManagerImpl manager, Scanner scanner) { // 删除联系人的方法
        System.out.print("请输入要删除的联系人姓名: "); // 打印删除提示
        String name = scanner.nextLine(); // 获取要删除的姓名
        if (manager.deleteContact(name)) // 调用deleteContact方法并判断结果
            System.out.println("删除成功！"); // 删除成功提示
        else
            System.out.println("未找到该联系人！"); // 未找到联系人提示
    }

    private static void updateContact(PhoneBookManagerImpl manager, Scanner scanner) { // 修改联系人的方法
        System.out.print("请输入要修改的联系人姓名: "); // 打印修改提示
        String name = scanner.nextLine(); // 获取要修改的姓名
        var contacts = manager.findContactsByName(name); // var关键字自动推断类型，查找匹配的联系人列表
        if (contacts.isEmpty()) { // isEmpty()检查集合是否为空
            System.out.println("未找到该联系人！"); // 未找到提示
            return; // return提前结束方法执行
        }
        Contact contact = contacts.get(0); // get(0)获取列表第一个元素

        System.out.print("新姓名(回车保持不变): "); // 打印姓名修改提示
        String newName = scanner.nextLine(); // 获取新姓名
        if (!newName.isEmpty()) // !取反运算符，检查字符串是否非空
            contact.setName(newName); // 调用setter方法更新姓名
        System.out.print("新性别(回车保持不变): "); // 打印性别修改提示
        String newGender = scanner.nextLine(); // 获取新性别
        if (!newGender.isEmpty()) // 检查是否非空
            contact.setGender(newGender); // 更新性别
        System.out.print("新年龄(输入-1保持不变): "); // 打印年龄修改提示
        int newAge = scanner.nextInt(); // 获取新年龄
        scanner.nextLine(); // 消耗回车符
        if (newAge != -1) // !=不等于运算符，检查年龄是否需要更新
            contact.setAge(newAge); // 更新年龄
        System.out.print("新地址(回车保持不变): "); // 打印地址修改提示
        String newAddress = scanner.nextLine(); // 获取新地址
        if (!newAddress.isEmpty()) // 检查地址是否非空
            contact.setAddress(newAddress); // 更新地址
        System.out.print("新电话(回车保持不变): "); // 打印电话修改提示
        String newPhone = scanner.nextLine(); // 获取新电话
        if (!newPhone.isEmpty()) // 检查电话是否非空
            contact.setPhoneNumber(newPhone); // 更新电话号码
        System.out.print("新邮箱(回车保持不变): "); // 打印邮箱修改提示
        String newEmail = scanner.nextLine(); // 获取新邮箱
        if (!newEmail.isEmpty()) // 检查邮箱是否非空
            contact.setEmail(newEmail); // 更新邮箱

        if (manager.updateContact(name, contact)) // 调用updateContact方法并判断结果
            System.out.println("修改成功！"); // 修改成功提示
        else
            System.out.println("修改失败！"); // 修改失败提示
    }

    private static void searchContact(PhoneBookManagerImpl manager, Scanner scanner) { // 查找联系人的方法
        System.out.print("请输入搜索关键字: "); // 打印搜索提示
        String keyword = scanner.nextLine(); // 获取搜索关键字
        var contacts = manager.findContactsByName(keyword); // 根据关键字查找联系人，返回List集合
        if (!contacts.isEmpty()) // 检查是否找到联系人
            System.out.println("找到联系人: " + contacts.get(0)); // 显示找到的第一个联系人，+用于字符串连接
        else
            System.out.println("未找到匹配的联系人！"); // 未找到匹配联系人提示
    }

    private static void showAllContacts(PhoneBookManagerImpl manager) { // 显示所有联系人的方法，只需要manager参数
        var contacts = manager.getAllContacts(); // 获取所有联系人列表
        if (contacts.isEmpty()) // 检查电话簿是否为空
            System.out.println("电话簿为空！"); // 空电话簿提示
        else { // else块处理有联系人的情况
            System.out.println("\n=== 所有联系人 ==="); // 打印标题，\n表示换行符
            for (Contact contact : contacts) // 增强for循环遍历集合，语法：for(元素类型 变量名 : 集合)
                System.out.println(contact); // 打印每个联系人，自动调用toString()方法
        }
    }
}